home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / iritsm3s.zip / VIEWOBJ.C < prev    next >
C/C++ Source or Header  |  1992-02-25  |  22KB  |  654 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d polygonal solid modeller.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber            Unix - X11 Ver 0.1, Mar. 1990    *
  5. ******************************************************************************
  6. * Module to handle viewing of objects in the ViewWindow.             *
  7. *****************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include "program.h"
  12. #include "attribut.h"
  13. #include "graphgen.h"
  14. #include "objects.h"
  15. #include "freeform.h"
  16. #include "geomat3d.h"
  17. #include "primitiv.h"
  18. #include "windows.h"
  19. #include "viewobj.h"
  20. #include "graphgen.h"
  21.  
  22. #define MAX_ROTATE_ANGLE    45.0 /* Maximum rates used by interact mode. */
  23. #define MAX_TRANSLATE_FACTOR    2.0
  24. #define MAX_SCALE_FACTOR    2.0
  25.  
  26. static int
  27.     ViewNormals = FALSE,
  28.     ClosedObject = FALSE,
  29.     SupportClosedObject = FALSE,
  30.     NormalsColor = 1,                  /* View normals to object. */
  31.     QuitView = FALSE;
  32. static RealType
  33.     LastCoord[3],           /* Used to store last point we moved/draw to. */
  34.     NormalsSize = 0.1;
  35. static ObjectStruct
  36.     *ActiveObjList = NULL;             /* Currently displayed objects. */
  37.  
  38. /* Prototypes for the View Object module: */
  39. static void InteractHandleInput(ObjectStruct *PObjList,
  40.                 MatrixType GlblViewMat, MatrixType GlblPrspMat);
  41. static MatrixType *ComputeCrntViewMatrix(void);
  42. static void ViewGeomObjectList(ObjectStruct *PObjList);
  43. static int GetInternal(void);
  44. static void ViewCagdPolyline(CagdPolylineStruct *Pl, int Color,
  45.                                  MatrixType Mat);
  46. static void TestQuitView(void);
  47. static void ViewPolygon(PolygonStruct *Pl, int Color, int IsPolyline,
  48.                     MatrixType Mat, int ViewInternal);
  49. static void DepthCueMoveTo(RealType Coord[3]);
  50. static void DepthCueDrawTo(RealType NewCoord[3]);
  51.  
  52. #ifdef __GL__
  53. static void DrawPolygonSolid(PolygonStruct *PPolygon, MatrixType Mat);
  54. #endif /* __GL__ */
  55.  
  56. /*****************************************************************************
  57. *  Routine to interactively display geometric object(s) PObj on the View     *
  58. * window enable rotating/translating/scaling it using the Input Device.      *
  59. *****************************************************************************/
  60. void InteractPolyObject(ObjectStruct *PObj, RealType *UpdateGlblMat)
  61. {
  62.     ObjectStruct *ViewMat, *PrspMat;
  63.     MatrixType ViewMatCopy, PrspMatCopy; /* Save original trans. to recover. */
  64.  
  65.     if (!GlblDoGraphics) return;
  66.  
  67.     if ((ViewMat = GetObject("VIEW_MAT")) == NULL) {
  68.     WndwInputWindowPutStr(
  69.         "No view transformation matrix VIEW_MAT!");
  70.     return;
  71.     }
  72.     else if (!IS_MAT_OBJ(ViewMat)) {
  73.     WndwInputWindowPutStr(
  74.         "VIEW_MAT object was modified (not matrix object)");
  75.     return;
  76.     }
  77.     MAT_COPY(ViewMatCopy, ViewMat -> U.Mat);
  78.  
  79.     if ((PrspMat = GetObject("PRSP_MAT")) == NULL) {
  80.     WndwInputWindowPutStr(
  81.         "No perspective transformation matrix PRSP_MAT!");
  82.     return;
  83.     }
  84.     else if (!IS_MAT_OBJ(PrspMat)) {
  85.     WndwInputWindowPutStr(
  86.         "PRSP_MAT object was modified (not matrix object)");
  87.     return;
  88.     }
  89.     MAT_COPY(PrspMatCopy, PrspMat -> U.Mat);
  90.  
  91.     /* Get data from input device, interpret it, and display interactively:  */
  92.     InteractHandleInput(PObj, ViewMat -> U.Mat, PrspMat -> U.Mat);
  93.  
  94.     if (!APX_EQ(*UpdateGlblMat, 0.0)) {
  95.     MAT_COPY(ViewMat -> U.Mat, ViewMatCopy);         /* Recover. */
  96.     MAT_COPY(PrspMat -> U.Mat, PrspMatCopy);
  97.     }
  98. }
  99.  
  100. /*****************************************************************************
  101. *  Routine to handle data from the input device (keyboard, mouse etc.) -     *
  102. * clip it against the sub windows of the interactive menu and perform the    *
  103. * required transfomation, by updating the global view matrix object VIEW_MAT *
  104. *  The input data in the Rotation/Translation/Scaling sub windows is used    *
  105. * (horizontal distance from sub window center) to set amount of change.         *
  106. *****************************************************************************/
  107. static void InteractHandleInput(ObjectStruct *PObjList,
  108.                 MatrixType GlblViewMat, MatrixType GlblPrspMat)
  109. {
  110.     int UpdateView;
  111.     RealType ChangeFactor;
  112.     MatrixType Mat, OrigViewMat, OrigPrspMat;
  113. #if !defined(__MSDOS__) && !defined(DJGCC)
  114.     long WinID, DispID, ColorMapID;
  115. #endif /* !__MSDOS__ && !DJGCC */
  116.  
  117.     /* Save copy of original matrix, so we can recover if reset is required. */
  118.     GEN_COPY(OrigViewMat, GlblViewMat, sizeof(MatrixType));
  119.     GEN_COPY(OrigPrspMat, GlblPrspMat, sizeof(MatrixType));
  120.  
  121.     ActiveObjList = PObjList;
  122.  
  123.     QuitView = FALSE;
  124.  
  125. #ifdef __MSDOS__
  126.     IntrWndwPop(TransWindowID, TRUE, TRUE);
  127. #endif /* __MSDOS__ */
  128.  
  129. #if defined(__MSDOS__) || defined(DJGCC)
  130.     GGClearViewArea();
  131.  
  132.     /* Set the async. function for intr_lib to refresh the view window. */
  133.     IntrWndwSetRefreshFunc(ViewWindowID,
  134.                (IntrIntFunc) UpdateInteractHandleInput);
  135. #endif /* __MSDOS__ || DJGCC */
  136.  
  137.     UpdateInteractHandleInput();       /* Display it for the first time. */
  138.  
  139.     while (TRUE) {
  140.     QuitView = FALSE;
  141.  
  142.     UpdateView = TRUE;
  143.  
  144.     switch (GGGetGraphicEvent(&ChangeFactor)) {
  145.         case EVENT_SCR_OBJ_TGL:    /* Its Coordinate system - toggle it. */
  146.         UpdateView = FALSE;
  147.         break;
  148.         case EVENT_PERS_ORTHO_TGL:           /* Its View mode - toggle it. */
  149.         MatGenUnitMat(Mat);
  150.         break;
  151.         case EVENT_PERS_ORTHO_Z: /* Its Perspective Z focal point modif. */
  152.         if (GlblViewMode != VIEW_PERSPECTIVE) {
  153.             GGTone(1000, 100);               /* Do some noise! */
  154.             UpdateView = FALSE;
  155.             break;
  156.         }
  157.         /* Make it between 0.5 and 1.5: */
  158.         ChangeFactor = ChangeFactor / 2.0 + 1.0;
  159.         GlblPrspMat[2][2] *= ChangeFactor;
  160.         GlblPrspMat[2][3] *= ChangeFactor;
  161.         GlblPrspMat[3][2] *= ChangeFactor;
  162.         MatGenUnitMat(Mat);
  163.         break;
  164.         case EVENT_ROTATE_X:       /* Its rotation along the X axis. */
  165.         MatGenMatRotX1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  166.         break;
  167.         case EVENT_ROTATE_Y:       /* Its rotation along the Y axis. */
  168.         MatGenMatRotY1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  169.         break;
  170.         case EVENT_ROTATE_Z:       /* Its rotation along the Z axis. */
  171.         MatGenMatRotZ1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  172.         break;
  173.         case EVENT_TRANSLATE_X:    /* Its translation along the X axis. */
  174.         MatGenMatTrans(ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0, 0.0,
  175.                                     Mat);
  176.         break;
  177.         case EVENT_TRANSLATE_Y:    /* Its translation along the Y axis. */
  178.         MatGenMatTrans(0.0, ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0,
  179.                                     Mat);
  180.         break;
  181.         case EVENT_TRANSLATE_Z:    /* Its translation along the Z axis. */
  182.         MatGenMatTrans(0.0, 0.0, ChangeFactor * MAX_TRANSLATE_FACTOR,
  183.                                     Mat);
  184.         break;
  185.         case EVENT_SCALE:              /* Its scaling along all axes. */
  186.         if (ChangeFactor > 0.0)              /* Make it around 1... */
  187.             ChangeFactor = ChangeFactor * MAX_SCALE_FACTOR + 1.0;
  188.         else
  189.             ChangeFactor = 1.0 /
  190.             (-ChangeFactor * MAX_SCALE_FACTOR + 1.0);
  191.         MatGenMatScale(ChangeFactor, ChangeFactor, ChangeFactor, Mat);
  192.         break;
  193.         case EVENT_DEPTH_CUE:
  194.         if (!GlblDepthCue) GGMySetLineStyle(SOLID_LINE);
  195.         MatGenUnitMat(Mat);
  196.         break;
  197. #ifdef __GL__                      /* Only on GL library systems. */
  198.         case EVENT_DRAW_SOLID:
  199.         MatGenUnitMat(Mat);
  200.         break;
  201. #else
  202.         case EVENT_DRAW_SOLID:
  203. #endif
  204.         case EVENT_SAVE_GIF:
  205.         case EVENT_SAVE_PS:
  206.         case EVENT_SAVE_MATRIX:
  207.         GGTone(800, 100);
  208.         GGTone(400, 200);
  209.         UpdateView = FALSE;
  210.         break;
  211.         case EVENT_RESET_MATRIX:
  212.         GEN_COPY(GlblViewMat, OrigViewMat, sizeof(MatrixType));
  213.         GEN_COPY(GlblPrspMat, OrigPrspMat, sizeof(MatrixType));
  214.         MatGenUnitMat(Mat);
  215.         break;
  216.         case EVENT_QUIT:
  217.         ActiveObjList = NULL;
  218. #ifdef __MSDOS__
  219.         IntrWndwPop(StatusWindowID, TRUE, TRUE);
  220. #endif /* __MSDOS__ */
  221.         return;                        /* Its Quit. */
  222.         default:
  223.         FatalError("InteractHandleInput: Undefine input type, exit\n");
  224.     }
  225.     if (UpdateView) {
  226.         switch (GlblTransformMode) {/* Udpate the global viewing matrix. */
  227.         case TRANS_SCREEN:
  228.             MatMultTwo4by4(GlblViewMat, GlblViewMat, Mat);
  229.             break;
  230.         case TRANS_OBJECT:
  231.             MatMultTwo4by4(GlblViewMat, Mat, GlblViewMat);
  232.             break;
  233.         }
  234.  
  235. #if defined(__MSDOS__) || defined(DJGCC)
  236.         GGClearViewArea();
  237. #endif /* __MSDOS__ || DJGCC */
  238.         UpdateInteractHandleInput();
  239.     }
  240.     }
  241. }
  242.  
  243. /*****************************************************************************
  244. *  Compute the current view using VIEW_MAT and PRSP_MAT matrices.         *
  245. *****************************************************************************/
  246. static MatrixType *ComputeCrntViewMatrix(void)
  247. {
  248.     static MatrixType CrntViewMat;
  249.     ObjectStruct *ViewMat, *PrspMat;
  250.  
  251.     if ((ViewMat = GetObject("VIEW_MAT")) == NULL) {
  252.     WndwInputWindowPutStr(
  253.         "No view transformation matrix VIEW_MAT!");
  254.     return NULL;
  255.     }
  256.     else if (!IS_MAT_OBJ(ViewMat)) {
  257.     WndwInputWindowPutStr(
  258.         "VIEW_MAT object was modified (not matrix object)");
  259.     return NULL;
  260.     }
  261.  
  262.     if ((PrspMat = GetObject("PRSP_MAT")) == NULL) {
  263.     WndwInputWindowPutStr(
  264.         "No perspective transformation matrix PRSP_MAT!");
  265.     return NULL;
  266.     }
  267.     else if (!IS_MAT_OBJ(PrspMat)) {
  268.     WndwInputWindowPutStr(
  269.         "PRSP_MAT object was modified (not matrix object)");
  270.     return NULL;
  271.     }
  272.  
  273.     switch (GlblViewMode) {
  274.     case VIEW_ORTHOGRAPHIC:
  275.         GEN_COPY(CrntViewMat, ViewMat -> U.Mat, sizeof(MatrixType));
  276.         break;
  277.     case VIEW_PERSPECTIVE:
  278.         MatMultTwo4by4(CrntViewMat, ViewMat -> U.Mat, PrspMat -> U.Mat);
  279.         break;
  280.     }
  281.  
  282.     return &CrntViewMat;
  283. }
  284.  
  285. /*****************************************************************************
  286. *  Routine to update the viewing screen. On unix systems this routine may    *
  287. * be invoked when X sends expose event to this program (see xgrphgen.c).     *
  288. * In MSDOS this routine is static and been called from InteractHandleInput   *
  289. * above routine only.                                 *
  290. *****************************************************************************/
  291. void UpdateInteractHandleInput(void)
  292. {
  293. #if !defined(__MSDOS__) && !defined(DJGCC)
  294.     GGClearViewArea();
  295. #endif /* !__MSDOS__ && !DJGCC */
  296.  
  297.     if (ActiveObjList != NULL)
  298.     ViewGeomObject(ActiveObjList);            /* And display it... */
  299.  
  300. #if !defined(__MSDOS__) && !defined(DJGCC)
  301.     GGGraphicFlush();
  302. #endif /* !__MSDOS__ && !DJGCC */
  303. }
  304.  
  305. /*****************************************************************************
  306. *  Routine to display the geometric objects in PObjList, by simply calling   *
  307. * ViewGeomObject on all of them. PObjList must be of type OBJ_LIST_OBJ.         *
  308. *****************************************************************************/
  309. static void ViewGeomObjectList(ObjectStruct *PObjList)
  310. {
  311.     int Param = 0;
  312.     ObjectStruct *PObj;
  313.  
  314.     while ((PObj = PObjList -> U.PObjList[Param]) != NULL &&
  315.        Param++ < MAX_OBJ_LIST && !QuitView) {
  316.     ViewGeomObject(PObj);
  317.     }
  318. }
  319.  
  320. /*****************************************************************************
  321. *  Routine to fetch the internal parameter from the INTERNAL object.         *
  322. *****************************************************************************/
  323. static int GetInternal(void)
  324. {
  325.     int Internal;
  326.     ObjectStruct *PObj = GetObject("INTERNAL");
  327.  
  328.     if (PObj == NULL || !IS_NUM_OBJ(PObj)) {
  329.     WndwInputWindowPutStr("No numeric object name INTERNAL is defined");
  330.     Internal = DEFAULT_INTERNAL;
  331.     }
  332.     else
  333.     Internal = !APX_EQ((PObj -> U.R), 0.0);
  334.  
  335.     return Internal;
  336. }
  337.  
  338. /*****************************************************************************
  339. *  Routine to display the geometric object PObj on the View Window:         *
  340. * Uses the global view transformation as computed by ComputeCrntViewMat.     *
  341. *****************************************************************************/
  342. void ViewGeomObject(ObjectStruct *PObj)
  343. {
  344.     int Color, IsPolyline,
  345.     DrawCtlPtColor = GetDrawCtlPt(),
  346.     ViewInternal = GetInternal(),
  347.     RealResolution = GetResolution(FALSE);
  348.     CagdPolylineStruct *CagdPl;
  349.     PolygonStruct *Pl;
  350.     MatrixType *CrntMat;
  351.  
  352.     if (!GlblDoGraphics) return;
  353.  
  354.     QuitView = FALSE;
  355.  
  356.     if (IS_OLST_OBJ(PObj)) {
  357.     /* Invoke the display routine on each of its componenets. */
  358.     ViewGeomObjectList(PObj);
  359.     return;
  360.     }
  361.  
  362.     if (!IS_GEOM_OBJ(PObj)) {
  363.     WndwInputWindowPutStr("None displayable object ignored.");
  364.         return;
  365.     }
  366.  
  367.     Color = GetObjectColor(PObj);
  368.  
  369.     if ((CrntMat = ComputeCrntViewMatrix()) == NULL)
  370.         return;
  371.  
  372.     if (IS_POLY_OBJ(PObj)) {
  373.     Pl = PObj -> U.Pl.P;
  374.  
  375.         IsPolyline = IS_POLYLINE_OBJ(PObj);
  376.  
  377.     if (!IsPolyline && SupportClosedObject)
  378.         ClosedObject = TRUE;
  379.  
  380.         while (Pl && !QuitView) {
  381.         ViewPolygon(Pl, Color, IsPolyline, *CrntMat, ViewInternal);
  382.         Pl = Pl -> Pnext;
  383.         TestQuitView();/* if break display in the middle - Set QuitView. */
  384.         }
  385.  
  386.     ClosedObject = FALSE;
  387.     }
  388.     else if (IS_CRV_OBJ(PObj)) {
  389.     if (!GlblDrawSolid) {
  390.         ComputeCurveIsoLines(PObj);
  391.  
  392.         if (RealResolution > 0)
  393.         ViewCagdPolyline(PObj -> U.Crv.PLPolys, Color, *CrntMat);
  394.         if (DrawCtlPtColor)
  395.         ViewCagdPolyline(PObj -> U.Crv.CtlPoly, DrawCtlPtColor,
  396.                  *CrntMat);
  397.     }
  398.     }
  399.     else if (IS_SRF_OBJ(PObj)) {
  400.     if (GlblDrawSolid) {
  401.         ComputeSurfacePolygons(PObj);
  402.         SetObjectColor(PObj -> U.Srf.Polygons, GetObjectColor(PObj));
  403.  
  404.         ViewGeomObject(PObj -> U.Srf.Polygons);
  405.     }
  406.     else {
  407.         ComputeSurfaceIsoLines(PObj);
  408.  
  409.         if (RealResolution > 0) {
  410.         CagdPl = PObj -> U.Srf.PLPolys;
  411.         while (CagdPl && !QuitView) {
  412.             ViewCagdPolyline(CagdPl, Color, *CrntMat);
  413.             CagdPl = CagdPl -> Pnext;
  414.             TestQuitView();/* Break display in middle - Set QuitView. */
  415.         }
  416.         }
  417.  
  418.         if (DrawCtlPtColor) {
  419.         CagdPl = PObj -> U.Srf.CtlMesh;
  420.         while (CagdPl && !QuitView) {
  421.             ViewCagdPolyline(CagdPl, DrawCtlPtColor, *CrntMat);
  422.             CagdPl = CagdPl -> Pnext;
  423.             TestQuitView();
  424.         }
  425.         }
  426.         }
  427.     }
  428. }
  429.  
  430. /*****************************************************************************
  431. *  Routine to display one polyline on the view window using the matrix Mat   *
  432. * as a transformation matrix.                             *
  433. *****************************************************************************/
  434. static void ViewCagdPolyline(CagdPolylineStruct *Pl, int Color,
  435.                                        MatrixType Mat)
  436. {
  437.     int i, j;
  438.     PointType P, TempP;
  439.     CagdPtStruct
  440.     *Points = Pl -> Polyline;
  441.  
  442.     /* Since we can not guarantee that CagdRType == RealType: */
  443.     for (i = 0; i < 3; i++) TempP[i] = Points[0].Pt[i];
  444.     MatMultVecby4by4(P, TempP, Mat);           /* Transform the first point. */
  445.     DepthCueMoveTo(P);
  446.  
  447.     GGMySetColor(Color);
  448.  
  449.     for (i = 1; i < Pl -> Length; i++) {
  450.     for (j = 0; j < 3; j++) TempP[j] = Points[i].Pt[j];
  451.     MatMultVecby4by4(P, TempP, Mat);
  452.     DepthCueDrawTo(P);
  453.     };
  454. }
  455.  
  456. /*****************************************************************************
  457. *  Routine to test if quit display event - occured -                 *
  458. * Right button was clicked on mouse.                         *
  459. *****************************************************************************/
  460. static void TestQuitView(void)
  461. {
  462.     QuitView = GGIsAbortKeyPressed();
  463. }
  464.  
  465. /*****************************************************************************
  466. *  Routine to display one polygon on the view window using the matrix Mat as *
  467. * a transformation matrix.                             *
  468. *****************************************************************************/
  469. static void ViewPolygon(PolygonStruct *Pl, int Color, int IsPolyline,
  470.                     MatrixType Mat, int ViewInternal)
  471. {
  472.     int NumOfPoints, DontDraw,
  473.     ShowNormals = ViewNormals && !IsPolyline;
  474.     PointType P, CenterP;
  475.     VertexStruct *V, *VStart;
  476.  
  477.     V = VStart = Pl -> V;
  478.     if (V == NULL) FatalError("ViewPolygon: Empty polygon to view\n");
  479.  
  480.     GGMySetColor(Color);
  481.  
  482. #ifdef __GL__                      /* Only on GL library systems. */
  483.     if (GlblDrawSolid && !IsPolyline) {
  484.     DrawPolygonSolid(Pl, Mat);
  485.     return;
  486.     }
  487. #endif
  488.  
  489.     MatMultVecby4by4(P, V -> Pt, Mat);           /* Transform the first point. */
  490.     DepthCueMoveTo(P);
  491.     DontDraw = IS_INTERNAL_EDGE(V) && !ViewInternal;      /* Draw next edge? */
  492.  
  493.     if (ShowNormals) {            /* If display of normal is required. */
  494.     NumOfPoints = 0;
  495.     PT_CLEAR(CenterP);
  496.     }
  497.  
  498.     do {
  499.     V = V -> Pnext;
  500.     if (ShowNormals) {
  501.         NumOfPoints++;
  502.         PT_ADD(CenterP, CenterP, V -> Pt);
  503.     }
  504.     MatMultVecby4by4(P, V -> Pt, Mat);
  505.     /* If edge is INTERNAL (Irit.h) and not ViewInternal - dont draw: */
  506.     if (DontDraw)
  507.         DepthCueMoveTo(P);
  508.     else
  509.         DepthCueDrawTo(P);
  510.  
  511.     DontDraw = IS_INTERNAL_EDGE(V) && !ViewInternal;  /* Draw next edge? */
  512.     } while (V != VStart && V -> Pnext != NULL);
  513.  
  514.     if (ShowNormals) {
  515.     PT_SCALE(CenterP, 1.0/NumOfPoints);        /* Estimate for normals. */
  516.     MatMultVecby4by4(P, CenterP, Mat);     /* Transform the first point. */
  517.     DepthCueMoveTo(P);
  518.     PT_COPY(P, Pl -> Plane);
  519.     PT_SCALE(P, NormalsSize);
  520.     PT_ADD(CenterP, CenterP, P);
  521.     MatMultVecby4by4(P, CenterP, Mat);    /* Transform the second point. */
  522.     GGMySetColor(NormalsColor);
  523.     DepthCueDrawTo(P);
  524.     }
  525. }
  526.  
  527. /*****************************************************************************
  528. *  Routine to set the normals default values:                     *
  529. *****************************************************************************/
  530. void ViewSetNormals(RealType *Active, RealType *Size, RealType *Color)
  531. {
  532.     ViewNormals = !APX_EQ(*Active, 0.0);
  533.     NormalsSize = *Size;
  534.     NormalsColor = (int) *Color;
  535. }
  536.  
  537. /*****************************************************************************
  538. *  Routine to set the closed objects default.                     *
  539. *****************************************************************************/
  540. void ViewSetClosed(RealType *Closed)
  541. {
  542.     SupportClosedObject = !APX_EQ(*Closed, 0.0);
  543. }
  544.  
  545. /*****************************************************************************
  546. * Routine to mave to 3D    point given as Coord[3], using Mat transform.         *
  547. *****************************************************************************/
  548. static void DepthCueMoveTo(RealType Coord[3])
  549. {
  550.     GEN_COPY(LastCoord, Coord, 3 * sizeof(RealType));     /* Set crnt point. */
  551. }
  552.  
  553. /*****************************************************************************
  554. * Routine to draw to 3D    point given as Coord[3], using Mat transform, from   *
  555. * the last point we moved to.                             *
  556. *****************************************************************************/
  557. static void DepthCueDrawTo(RealType NewCoord[3])
  558. {
  559.     RealType MiddleCoord[3], t;
  560.  
  561.     if (ClosedObject && NewCoord[2] < LastCoord[2]) {
  562.     GEN_COPY(LastCoord, NewCoord, 3 * sizeof(RealType));
  563.     return;
  564.     }
  565.  
  566.     /* Implementation of simple depth cue - if line is >Z or <Z ... */
  567.     if (LastCoord[2] <= 0.0 && NewCoord[2] <= 0.0) {    /* Draw the <Z part: */
  568.  
  569.     if (GlblDepthCue) GGMySetLineStyle(DOTTED_LINE);
  570.  
  571.     GGMyMove(LastCoord[0], LastCoord[1]);
  572.     GGMyDraw(NewCoord[0], NewCoord[1]);                /* DRAW! */
  573.     }
  574.     else if (LastCoord[2] >= 0.0 && NewCoord[2] >= 0.0 ||
  575.          ABS(LastCoord[2] - NewCoord[2]) < EPSILON) {
  576.     if (GlblDepthCue) GGMySetLineStyle(SOLID_LINE);
  577.  
  578.     GGMyMove(LastCoord[0], LastCoord[1]);
  579.     GGMyDraw(NewCoord[0], NewCoord[1]);                /* DRAW! */
  580.     }
  581.     else {                      /* Line intersect Z = 0 plane. */
  582.     t = LastCoord[2] / (LastCoord[2] - NewCoord[2]);
  583.     MiddleCoord[0] = LastCoord[0] * (1.0 - t) + NewCoord[0] * t;
  584.     MiddleCoord[1] = LastCoord[1] * (1.0 - t) + NewCoord[1] * t;
  585.  
  586.     if (GlblDepthCue) GGMySetLineStyle(SOLID_LINE);
  587.  
  588.     if (LastCoord[2] > 0.0) {
  589.         GGMyMove(LastCoord[0], LastCoord[1]);
  590.         GGMyDraw(MiddleCoord[0], MiddleCoord[1]);            /* DRAW! */
  591.     }
  592.     else {
  593.         GGMyMove(MiddleCoord[0], MiddleCoord[1]);
  594.         GGMyDraw(NewCoord[0], NewCoord[1]);                /* DRAW! */
  595.     }
  596.  
  597.     if (GlblDepthCue) GGMySetLineStyle(DOTTED_LINE);/* Draw the <Z part: */
  598.  
  599.     if (LastCoord[2] < 0.0) {
  600.         GGMyMove(LastCoord[0], LastCoord[1]);
  601.         GGMyDraw(MiddleCoord[0], MiddleCoord[1]);            /* DRAW! */
  602.     }
  603.     else {
  604.         GGMyMove(MiddleCoord[0], MiddleCoord[1]);
  605.         GGMyDraw(NewCoord[0], NewCoord[1]);                /* DRAW! */
  606.     }
  607.     }
  608.  
  609.     GEN_COPY(LastCoord, NewCoord, 3 * sizeof(RealType));  /* Set crnt point. */
  610. }
  611.  
  612. #ifdef __GL__
  613.  
  614. /****************************************************************************
  615. * Routine to draw a polygon full.                        *
  616. ****************************************************************************/
  617. static void DrawPolygonSolid(PolygonStruct *PPolygon, MatrixType Mat)
  618. {
  619.     int i, l = 0;
  620.     float Normal[3], Length;
  621.     double MappedVertex[3];
  622.     RealType V1R[3], V2R[3], V3R[3];
  623.     VertexStruct *PList = PPolygon -> V;
  624.  
  625.     GGMyDrawPolygonSolid(NULL, NULL, TRUE);
  626.  
  627.     do {
  628.     MatMultVecby4by4(V1R, PList -> Pt, Mat);
  629.     for (i = 0; i < 3; i++) MappedVertex[i] = V1R[i];
  630.  
  631.     /* Each vertex has different normal - specify them. */
  632.     MatMultVecby4by4(V1R, PList -> Pt, Mat);
  633.     for (i = 0; i < 3; i++)
  634.         V2R[i] = PList -> Pt[i] + PList -> Normal[i];
  635.     MatMultVecby4by4(V2R, V2R, Mat);
  636.     for (i = 0; i < 3; i++) Normal[i] = V2R[i] - V1R[i];
  637.     Length = sqrt(SQR(Normal[0]) + SQR(Normal[1]) + SQR(Normal[2]));
  638.     for (i = 0; i < 3; i++) Normal[i] /= -Length;
  639.  
  640.     GGMyDrawPolygonSolid(MappedVertex, Normal, TRUE);
  641.  
  642.     PList = PList -> Pnext;
  643.  
  644.     if (l++ >= 255)
  645.         FatalError("GL: polygon too complex (> 256 vertices).\n");        
  646.     }
  647.     while (PList != NULL && PList != PPolygon -> V);
  648.  
  649.     GGMyDrawPolygonSolid(NULL, NULL, FALSE);
  650. }
  651.  
  652. #endif /* __GL__ */
  653.  
  654.